package com.ruoyi.common.utils.poi;




import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.utils.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author silence
 * @date 2024-02-01 15:37
 */
public class CsvUtil {

    private static final String COLUMN_SEPARATOR = ",";
    private static final String ROW_SEPARATOR = "\n";

    public static <T> void writeListToCsv(HttpServletResponse response, List<T> dataList,List<Object[]> objects) {

        // 设置响应头
        response.setContentType("text/csv");
        response.setHeader("Content-Disposition", "attachment; filename=data.csv");

        // 使用PrintWriter将CSV写入响应
        PrintWriter writer = null;
        try {
            writer = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8));
            T obj;
            if(dataList != null && dataList.size() > 0){
                obj = dataList.get(0);
            }else{
                return;
            }
            StringBuilder strline = new StringBuilder();
//            Field[] fields = obj.getClass().getDeclaredFields();
            for (int i = 0; i < objects.size(); i++) {
                Excel attr = (Excel) objects.get(i)[1];
//                Field field = objects[i];
//                field.setAccessible(true);
                if(i<objects.size()-1){
                    strline.append(attr.name()).append(COLUMN_SEPARATOR);
                }else{
                    strline.append(attr.name()).append(ROW_SEPARATOR);
                }
            }
            for (T data : dataList) {
                String csvLine = convertToCsvLine(data,strline,objects);
                if(StringUtils.isNotBlank(csvLine)){
                    writer.append(csvLine);
                    Boolean allFieldsIsNull = false;
                    try {
                        allFieldsIsNull = isAllFieldsNull(data);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    if(!allFieldsIsNull){
                        writer.append(ROW_SEPARATOR);
                    }
                    strline = new StringBuilder();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            writer.flush();
            writer.close();
        }



    }

    private static <T> String convertToCsvLine(T data, StringBuilder csvLine,List<Object[]> objects) {
        // 根据实际情况，将对象的属性拼接成CSV格式的一行数据
        // 这里假设对象是一个包含字符串属性的类，你需要根据实际情况修改
        Boolean allFieldsIsNull = false;
        try {
            allFieldsIsNull = isAllFieldsNull(data);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        if (data == null || allFieldsIsNull) {

        }else{
//            Field[] fields = data.getClass().getDeclaredFields();
            for (int i = 0; i < objects.size(); i++) {
                Field field =(Field) objects.get(i)[0];
                field.setAccessible(true);
                try {
                    Object value = field.get(data);
                    if (value != null) {
                        csvLine.append(value.toString()).append(COLUMN_SEPARATOR);
                    } else {
                        // Treat null values as empty strings
                        csvLine.append(COLUMN_SEPARATOR);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            // Remove the last COLUMN_SEPARATOR
            if (csvLine.length() > 0) {
                csvLine.setLength(csvLine.length() - COLUMN_SEPARATOR.length());
            }
        }
        return csvLine.toString();
    }


    private static boolean isAllFieldsNull(Object obj) throws IllegalAccessException {
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.get(obj) != null) {
                return false;
            }
        }
        return true;
    }

    private static String convertCamelCaseToUnderscore(String camelCase) {
        if (camelCase == null || camelCase.isEmpty()) {
            return camelCase;
        }

        StringBuilder result = new StringBuilder();
        result.append(Character.toLowerCase(camelCase.charAt(0)));

        for (int i = 1; i < camelCase.length(); i++) {
            char currentChar = camelCase.charAt(i);

            if (Character.isUpperCase(currentChar)) {
                result.append("_").append(Character.toLowerCase(currentChar));
            } else {
                result.append(currentChar);
            }
        }

        return result.toString();
    }

}
